package com.gitee.apanlh.util.net.http;

import com.gitee.apanlh.exp.HttpStatusException;
import com.gitee.apanlh.exp.UnknownTypeException;
import com.gitee.apanlh.util.encode.StrEncodeUtils;

/**	
 * 	默认实现HTTP响应状态
 * 	
 * 	@author Pan
 */
public class HttpStatus implements BaseHttpStatus {
	
	/** HTTP客户端 */
	private HttpClient httpClient;
	/** 返回状态 */
	private Integer responseCode;
	/** 返回消息 */
	private String responseMsg;
	/** 返回错误信息 */
	private String errorStr;
	
	/**	
	 * 	默认-构造函数
	 * 	
	 * 	@author Pan
	 * 	@param 	httpClient	HTTP客户端
	 */
	public HttpStatus(HttpClient httpClient) {
		this.httpClient = httpClient;
	}
	
	@Override
	public String getMessage() {
		try {
			if (responseMsg == null) {
				this.responseMsg = httpClient.getClient().getResponseMessage();
			}
			return this.responseMsg; 
		} catch (Exception e) {
			throw new HttpStatusException(e.getMessage(), e);
		}
	} 
	
	@Override
	public String getErrorMsg() {
		return this.errorStr;
	}
	
	@Override
	public Integer getCode() {
		try {
			if (responseCode == null) {
				this.responseCode = httpClient.getClient().getResponseCode();
			}
			return this.responseCode; 
		} catch (Exception e) {
			throw new HttpStatusException(e.getMessage(), e);
		}
	} 
	
	@Override
    public boolean isSuc() {
		return is2xxStatusCode();
    }
    
	@Override
    public boolean isError() {
    	return is4xxStatusCode() || is5xxStatusCode();
    }
    
    /**
     * 	判断是否代表1系列HTTP状态 
     * 	<br>{@link HttpStatusEnums}
     * 	<br>informational
     * 	
     * 	@author Pan
     * 	@return	boolean
     */
    public boolean is1xxStatusCode() {
    	return isStatusType(HttpStatusEnums.TYPE_INFORMATIONAL.getType());
    }
    
    /**
     * 	判断是否代表2系列HTTP状态 
     * 	<br>{@link HttpStatusEnums}
     * 	<br>successful
     * 	
     * 	@author Pan
     * 	@return	boolean
     */
    public boolean is2xxStatusCode() {
    	return isStatusType(HttpStatusEnums.TYPE_SUCCESSFUL.getType());
    }
    
    /**
     * 	判断是否代表3系列HTTP状态 
     * 	<br>{@link HttpStatusEnums}
     * 	<br>redirection
     * 	
     * 	@author Pan
     * 	@return	boolean
     */
    public boolean is3xxStatusCode() {
    	return isStatusType(HttpStatusEnums.TYPE_REDIRECTION.getType());
    }
    
    /**
     * 	判断是否代表4系列HTTP状态 
     * 	<br>{@link HttpStatusEnums}
     * 	<br>clientError
     * 	
     * 	@author Pan
     * 	@return	boolean
     */
    public boolean is4xxStatusCode() {
    	return isStatusType(HttpStatusEnums.TYPE_CLIENT_ERROR.getType());
    }
    
    /**
     * 	判断是否代表5系列HTTP状态 
     * 	<br>{@link HttpStatusEnums}
     * 	<br>serverError
     * 	
     * 	@author Pan
     * 	@return	boolean
     */
    public boolean is5xxStatusCode() {
    	return isStatusType(HttpStatusEnums.TYPE_SERVER_ERROR.getType());
    }
    
    /**	
     * 	根据传递的HTTP类型值，判断是否属于某种HTTP类型
     * 
     * 	@author Pan
     * 	@param 	type	HTTP类型
     * 	@return	boolean
     */
    private boolean isStatusType(int type) {
    	if (this.getCode() == null) {
    		throw new UnknownTypeException("unknown http status");
    	}
    	return this.getCode() / 100 == type;
    }

    /**	
     * 	设置-错误响应消息
     * 	
     * 	@author Pan
     * 	@param 	responseBody	响应体
     * 	@param 	charset			字符编码集
     */
    protected void setErrorMsg(byte[] responseBody, String charset) {
    	this.errorStr = StrEncodeUtils.utf8EncodeToStr(responseBody, charset);
    }
    
    /**	
     * 	创建HTTP状态
     * 	
     * 	@author Pan
     * 	@param 	httpClient	HTTP客户端
     * 	@return	HttpStatus
     */
    public static HttpStatus create(HttpClient httpClient) {
    	return new HttpStatus(httpClient);
    }

}
